/**

 @Name：layuiAdmin 视图模块
 @Author：贤心
 @Site：http://www.layui.com/admin/
 @License：LPPL

 */

layui.define(['laytpl', 'layer'], function (exports) {
	var $ = layui.jquery
			, laytpl = layui.laytpl
			, layer = layui.layer
			, setter = layui.setter
			, device = layui.device()
			, hint = layui.hint()

			//对外接口
			, view = function (id) {
				return new Class(id);
			}

			, SHOW = 'layui-show', LAY_BODY = 'LAY_app_body'

			//构造器
			, Class = function (id) {
				this.id = id;
				this.container = $('#' + (id || LAY_BODY));
			};

	//加载中
	view.loading = function (elem) {
		elem.append(
				this.elemLoad = $('<i class="layui-anim layui-anim-rotate layui-anim-loop layui-icon layui-icon-loading layadmin-loading"></i>')
		);
	};

	//移除加载
	view.removeLoad = function () {
		this.elemLoad && this.elemLoad.remove();
	};

	//清除 token，并跳转到登入页
	view.exit = function (callback) {
		//清空本地记录的 token
		layui.data(setter.tableName, {
			key: setter.request.tokenName
			, remove: true
		});

		//跳转到登入页
		//location.hash = '/user/login';
		callback && callback();
	};

	//Ajax请求
	view.req = function (options) {
		var that = this
				, success = options.success
				, error = options.error
				, request = setter.request
				, response = setter.response
				, debug = function () {
			return setter.debug
					? '<br><cite>URL：</cite>' + options.url
					: '';
		};

		options.data = options.data || {};
		options.headers = options.headers || {};

		if (request.tokenName) {
			var sendData = typeof options.data === 'string'
					? JSON.parse(options.data)
					: options.data;

			//自动给参数传入默认 token
			options.data[request.tokenName] = request.tokenName in sendData
					? options.data[request.tokenName]
					: (layui.data(setter.tableName)[request.tokenName] || '');

			//自动给 Request Headers 传入 token
			options.headers[request.tokenName] = request.tokenName in options.headers
					? options.headers[request.tokenName]
					: (layui.data(setter.tableName)[request.tokenName] || '');
		}

		delete options.success;
		delete options.error;

		return $.ajax($.extend({
			type: 'get'
			, dataType: 'json'
			, success: function (res) {
				var statusCode = response.statusCode;

				//只有 response 的 code 一切正常才执行 done
				if (res[response.statusName] == statusCode.ok) {
					typeof options.done === 'function' && options.done(res);
				}

				//登录状态失效，清除本地 access_token，并强制跳转到登入页
				else if (res[response.statusName] == statusCode.logout) {
					view.exit();
				}

				//其它异常
				else {
					var error = [
						'<cite>Error：</cite> ' + (res[response.msgName] || '返回状态码异常')
						, debug()
					].join('');
					view.error(error);
				}

				//只要 http 状态码正常，无论 response 的 code 是否正常都执行 success
				typeof success === 'function' && success(res);
			}
			, error: function (e, code) {
				var error = [
					'请求异常，请重试<br><cite>错误信息：</cite>' + code
					, debug()
				].join('');
				view.error(error);

				typeof error === 'function' && error(res);
			}
		}, options));
	};

	//弹窗
	view.popup = function (options) {
		var success = options.success
				, skin = options.skin;

		delete options.success;
		delete options.skin;

		return layer.open($.extend({
			type: 1
			, title: '提示'
			, content: ''
			, id: 'LAY-system-view-popup'
			, skin: 'layui-layer-admin' + (skin ? ' ' + skin : '')
			, shadeClose: true
			, closeBtn: false
			, success: function (layero, index) {
				var elemClose = $('<i class="layui-icon" close>&#x1006;</i>');
				layero.append(elemClose);
				elemClose.on('click', function () {
					layer.close(index);
				});
				typeof success === 'function' && success.apply(this, arguments);
			}
		}, options))
	};

	//异常提示
	view.error = function (content, options) {
		return view.popup($.extend({
			content: content
			, maxWidth: 300
			//,shade: 0.01
			, offset: 't'
			, anim: 6
			, id: 'LAY_adminError'
		}, options))
	};


	//请求模板文件渲染
	Class.prototype.render = function (views, params) {
		var that = this, router = layui.router();
		views = setter.views + views + setter.engine;

		$('#' + LAY_BODY).children('.layadmin-loading').remove();
		view.loading(that.container); //loading

		//请求模板
		$.ajax({
			url: views
			, type: 'get'
			, dataType: 'html'
			, data: {
				v: layui.cache.version
			}
			, success: function (html) {
				html = '<div>' + html + '</div>';

				var elemTitle = $(html).find('title')
						, title = elemTitle.text() || (html.match(/\<title\>([\s\S]*)\<\/title>/) || [])[1];

				var res = {
					title: title
					, body: html
				};

				elemTitle.remove();
				that.params = params || {}; //获取参数

				if (that.then) {
					that.then(res);
					delete that.then;
				}

				that.parse(html);
				view.removeLoad();

				if (that.done) {
					that.done(res);
					delete that.done;
				}

			}
			, error: function (e) {
				view.removeLoad();

				if (that.render.isError) {
					return view.error('请求视图文件异常，状态：' + e.status);
				}
				;

				if (e.status === 404) {
					that.render('template/tips/404');
				} else {
					that.render('template/tips/error');
				}

				that.render.isError = true;
			}
		});
		return that;
	};

	//解析模板
	Class.prototype.parse = function (html, refresh, callback) {
		var that = this
				, isScriptTpl = typeof html === 'object' //是否模板元素
				, elem = isScriptTpl ? html : $(html)
				, elemTemp = isScriptTpl ? html : elem.find('*[template]')
				, fn = function (options) {
			var tpl = laytpl(options.dataElem.html())
					, res = $.extend({
				params: router.params
			}, options.res);

			options.dataElem.after(tpl.render(res));
			typeof callback === 'function' && callback();

			try {
				options.done && new Function('d', options.done)(res);
			} catch (e) {
				console.error(options.dataElem[0], '\n存在错误回调脚本\n\n', e)
			}
		}
				, router = layui.router();

		elem.find('title').remove();
		that.container[refresh ? 'after' : 'html'](elem.children());

		router.params = that.params || {};

		//遍历模板区块
		for (var i = elemTemp.length; i > 0; i--) {
			(function () {
				var dataElem = elemTemp.eq(i - 1)
						, layDone = dataElem.attr('lay-done') || dataElem.attr('lay-then') //获取回调
						, url = laytpl(dataElem.attr('lay-url') || '').render(router) //接口 url
						, data = laytpl(dataElem.attr('lay-data') || '').render(router) //接口参数
						, headers = laytpl(dataElem.attr('lay-headers') || '').render(router); //接口请求的头信息

				try {
					data = new Function('return ' + data + ';')();
				} catch (e) {
					hint.error('lay-data: ' + e.message);
					data = {};
				}
				;

				try {
					headers = new Function('return ' + headers + ';')();
				} catch (e) {
					hint.error('lay-headers: ' + e.message);
					headers = headers || {}
				}
				;

				if (url) {
					view.req({
						type: dataElem.attr('lay-type') || 'get'
						, url: url
						, data: data
						, dataType: 'json'
						, headers: headers
						, success: function (res) {
							fn({
								dataElem: dataElem
								, res: res
								, done: layDone
							});
						}
					});
				} else {
					fn({
						dataElem: dataElem
						, done: layDone
					});
				}
			}());
		}

		return that;
	};

	//自动渲染数据模板
	Class.prototype.autoRender = function (id, callback) {
		var that = this;
		$(id || 'body').find('*[template]').each(function (index, item) {
			var othis = $(this);
			that.container = othis;
			that.parse(othis, 'refresh');
		});
	};

	//直接渲染字符
	Class.prototype.send = function (views, data) {
		var tpl = laytpl(views || this.container.html()).render(data || {});
		this.container.html(tpl);
		return this;
	};

	//局部刷新模板
	Class.prototype.refresh = function (callback) {
		var that = this
				, next = that.container.next()
				, templateid = next.attr('lay-templateid');

		if (that.id != templateid) return that;

		that.parse(that.container, 'refresh', function () {
			that.container.siblings('[lay-templateid="' + that.id + '"]:last').remove();
			typeof callback === 'function' && callback();
		});

		return that;
	};

	//视图请求成功后的回调
	Class.prototype.then = function (callback) {
		this.then = callback;
		return this;
	};

	//视图渲染完毕后的回调
	Class.prototype.done = function (callback) {
		this.done = callback;
		return this;
	};

	//对外接口
	exports('view', view);
});